﻿using System;
using System.Collections.Specialized;
using System.Collections.Generic;
using System.Data;
using System.Collections;
using System.Linq;
using System.Text;
using System.Reflection;

namespace IntraVision.Web.Toolkit
{
    public class DataBinder
    {
        public static bool AreEqual(object o1, object o2)
        {
            bool flag = false;
            if ((o1 == null) && (o2 == null))
            {
                return true;
            }
            if (o1 != null)
            {
                Type conversionType = o1.GetType();
                o2 = Convert.ChangeType(o2, conversionType);
                flag = o1.Equals(o2);
            }
            return flag;
        }

        public static DataTable EvalDataSource(object dataSource, string textField, string valueField)
        {
            if (dataSource == null) return new DataTable();

            DataTable tbl = null;
            if (string.IsNullOrEmpty(textField) && string.IsNullOrEmpty(valueField))
            {
                tbl = SourceToTable(dataSource);
                ValidateDataSource(tbl);
                return tbl;
            }
            if (!(string.IsNullOrEmpty(textField) || !string.IsNullOrEmpty(valueField)))
            {
                tbl = SourceToTable(dataSource, new object[] { textField, textField });
            }
            else
            {
                tbl = SourceToTable(dataSource, new object[] { valueField, textField });
            }
            ValidateDataSource(tbl);
            return tbl;
        }

        protected static void ValidateDataSource(DataTable tbl)
        {
            if (tbl == null)
            {
                throw new Exception("Invalid data source. There must be at least one column/property present");
            }
            if (tbl.Columns.Count < 1)
            {
                throw new Exception("Invalid data source. Must be IEnumerable, IQueryable, a DataSet, a DataTable, or an IDataReader");
            }
        } 

        protected static DataTable CopyTable(DataTable tblFrom, object[] keeperColumns)
        {
            DataTable table = new DataTable();
            if (keeperColumns != null)
            {
                foreach (DataColumn column in tblFrom.Columns)
                {
                    string str = column.ColumnName.ToLower().Trim();
                    foreach (object obj2 in keeperColumns)
                    {
                        if (obj2.ToString().ToLower().Equals(str))
                        {
                            table.Columns.Add(str);
                            break;
                        }
                    }
                }
            }
            else
            {
                table = tblFrom.Clone();
            }
            foreach (DataRow row in tblFrom.Rows)
            {
                DataRow row2 = table.NewRow();
                foreach (DataColumn column2 in table.Columns)
                {
                    row2[column2.ColumnName] = row[column2.ColumnName];
                }
                table.Rows.Add(row2);
            }
            return table;
        }

        protected static PropertyInfo FindProp(string propName, PropertyInfo[] props)
        {
            foreach (PropertyInfo info2 in props)
            {
                if (info2.Name.ToLower().Trim().Equals(propName.ToLower().Trim()))
                {
                    return info2;
                }
            }
            return null;
        }

        public static DataTable SourceToTable(object dataSource) { return SourceToTable(dataSource, null); }

        public static DataTable SourceToTable(object dataSource, params object[] dataSourceKeys)
        {
            DataRow row;
            DataTable table = new DataTable();
            IEnumerator enumerator = null;
            if (dataSource is IDataReader)
            {
                DataColumn column;
                IDataReader reader = dataSource as IDataReader;
                if (dataSourceKeys != null)
                {
                    foreach (object obj2 in dataSourceKeys)
                    {
                        column = new DataColumn();
                        column.ColumnName = obj2.ToString();
                        table.Columns.Add(column);
                    }
                }
                while (reader.Read())
                {
                    row = table.NewRow();
                    string str = "";
                    if (dataSourceKeys != null)
                    {
                        foreach (object obj2 in dataSourceKeys)
                        {
                            str = reader[obj2.ToString()].ToString();
                            row[obj2.ToString()] = str;
                        }
                    }
                    else
                    {
                        if (table.Columns.Count == 0)
                        {
                            for (int j = 0; j < reader.FieldCount; j++)
                            {
                                column = new DataColumn(reader.GetName(j));
                                table.Columns.Add(column);
                            }
                        }
                        foreach (DataColumn col in table.Columns)
                        {
                            str = reader[col.ColumnName].ToString();
                            row[col.ColumnName] = str;
                        }
                    }
                    table.Rows.Add(row);
                }
                reader.Close();
                return table;
            }
            if ((dataSource is DataSet) || (dataSource is DataTable))
            {
                DataTable tblFrom = null;
                if (dataSource is DataSet)
                {
                    DataSet set = dataSource as DataSet;
                    if (set.Tables.Count > 0)
                    {
                        tblFrom = set.Tables[0];
                    }
                }
                else
                {
                    tblFrom = dataSource as DataTable;
                }
                return CopyTable(tblFrom, dataSourceKeys);
            }
            if (dataSource is NameValueCollection)
            {
                table.Columns.Add("Value");
                table.Columns.Add("Text");
                var nvc = dataSource as NameValueCollection;
                foreach (string key in nvc.AllKeys)
                {
                    row = table.NewRow();
                    row[0] = key;
                    row[1] = nvc[key];
                    table.Rows.Add(row);
                }
                return table;
            }
            if (dataSource is Array)
            {
                table.Columns.Add("Value");
                table.Columns.Add("Text");
                enumerator = (dataSource as IEnumerable<object>).GetEnumerator();
                int i = 0;
                while (enumerator.MoveNext())
                {
                    row = table.NewRow();
                    row[0] = i;
                    row[1] = enumerator.Current.ToString();
                    table.Rows.Add(row);
                    i++;
                }
                return table;
            }
            if (dataSource is IQueryable)
            {
                enumerator = (dataSource as IQueryable).GetEnumerator();
            }
            else if (dataSource is IEnumerable)
            {
                enumerator = (dataSource as IEnumerable).GetEnumerator();
            }
            if (enumerator == null)
            {
                throw new Exception("Can't bind to that data source. Consider using an IEnumerable data source such as an Array or collection");
            }
            PropertyInfo[] props = null;
            if (dataSourceKeys != null)
            {
                foreach (object obj2 in dataSourceKeys)
                {
                    table.Columns.Add(new DataColumn(obj2.ToString()));
                }
            }
            for (int i = 0; enumerator.MoveNext(); i++)
            {
                if (i == 0)
                {
                    props = enumerator.Current.GetType().GetProperties();
                    if (dataSourceKeys == null)
                    {
                        foreach (PropertyInfo info in props)
                        {
                            table.Columns.Add(new DataColumn(info.Name));
                        }
                    }
                }
                row = table.NewRow();
                if (dataSourceKeys != null)
                {
                    foreach (object obj2 in dataSourceKeys)
                    {
                        row[obj2.ToString()] = FindProp(obj2.ToString(), props).GetValue(enumerator.Current, null);
                    }
                }
                else
                {
                    foreach (PropertyInfo info in props)
                    {
                        row[info.Name] = info.GetValue(enumerator.Current, null);
                    }
                }
                table.Rows.Add(row);
            }
            return table;
        }
    }
}
